//Name: Cao Dung Anh
//Class: 11CTT
//Sid: 1151003

#include "UserList.h"
#include "UserInfo.h"
#include <iostream>
using namespace std;
#include <fstream>
#include <string>

//constructor
UserList::UserList()
{
	head = NULL;
	subhead = NULL;
	loadUserList();
}

//add user to file
void UserList::addUsertoFile()
{
	UserInfo temp;
	
	temp.addUser();

	ofstream file;

	file.open("UserInfo.bin",ios::binary | ios::ate | ios::app);

	file.write((char*)&temp,sizeof(UserInfo));

	file.close();

	updateUserList();
	loadUserList();
}

//Add user to file with specify user type
void UserList::addUsertoFile(int usertype)
{
	UserInfo temp;
	//cin.get();
	char name[100];
	char username[100];
	cout << "Your name: ";
	cin.getline(name,sizeof(name));
	strcpy(name,temp.normalizeName(name));
	strcpy(username,temp.createUsernamefromName(name));
	cout << "Your username will be: " << username << endl;
	while (checkUserName(username))
	{
		cout << "This username has been exist in the database\n"
			<< "You have to enter your username manually\n"
			<< "Your username: ";
		cin >> username;
		cin.get();
		//need to be valid
	}

	temp.addUser(usertype,username,name);

	ofstream file;

	file.open("UserInfo.bin",ios::binary | ios::ate | ios::app);

	file.write((char*)&temp,sizeof(temp));

	file.close();

	//updateUserList();
	loadUserList();
}

//Load list of user into linked list
void UserList::loadUserList()
{
	if (head != NULL)
	{
		freeHead();
	}
	Node *cur;
	ifstream file;

	file.open("UserInfo.bin",ios::binary);

	UserInfo buffer;
	while(file.read((char*)&buffer,sizeof(buffer)) != NULL)
	{
		Node* newNode = new Node;
		newNode->data.copyInfo(buffer);
		newNode->next = NULL;
		if (head == NULL)
		{
			head = newNode;
		}
		else
		{
			cur = head;
			while (cur->next != NULL)
			{
				cur=cur->next;
			}
			cur->next=newNode;
		}
	}

	file.close();
}


//Update the new information to database
void UserList::updateUserList()
{
	if (head == NULL)
	{
		cout << "The list is empty or the list has not been loaded at the beginning\n";
		return;
	}
	Node *cur = head;
	UserInfo temp;
	ofstream file;
	file.open("UserInfo.bin",ios::binary);

	while (cur)
	{
		temp.copyInfo(cur->data);
		file.write((char*)&temp,sizeof(temp));
		cur = cur->next;
	}

	file.close();
}

//Show all list of user
bool UserList::showAllForAdmin()
{
	freeSubhead();
	if (head == NULL)
	{
		cout << "List empty";
		return false;
	}
	int count = 0;
	Node *cur = head;
	while (cur)
	{
		if (cur->data.getStatus() != 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}
	if (count == 0)
	{
		return false;
	}
	return true;
}

//Show all information about the readers for librarian
bool UserList::showAllForLib()
{
	freeSubhead();
	if (head == NULL)
	{
		cout << "List empty";
		return false;
	}
	int count = 0;
	Node *cur = head;
	//if cur is not null and data is of readers (User-type = 3) and the reader's account is not deleted (status != 3)
	while (cur)
	{
		if (cur->data.getUserType() == 3 && cur->data.getStatus() != 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}
	if (count == 0)
	{
		return false;
	}
	return true;
}

//Show the information in the sublist
void UserList::showsublist()
{
	if (subhead == NULL)
	{
		cout << "List empty";
		return;
	}
	int count = 0;
	Node *cur = subhead;
	while (cur)
	{
		cout << endl;
		cout << ++count << "--------------------------\n\n";
		cur->data.showInfo();
		cur = cur->next;
		cout << endl;
	}
}

//Check Username
bool UserList::checkUserName(char *username)
{
	Node *cur = head;
	while (cur)
	{
		if (cur->data.isExist(username) == true)
		{
			return true;
		}
		cur = cur->next;
	}
	return false;
}

//check Account existence and return user type
char* UserList::checkAccount(char *username,char *pass)
{
	Node *cur = head;
	while(cur)
	{
		if (cur->data.isExist(username,pass))
		{
			if(cur->data.getStatus()==3)
			{
				return "3";
			}
			return cur->data.getUserName();
		}
		cur = cur->next;
	}
	return NULL;
}
//New Update check Type of User
int UserList::checkUserType(char *username)
{
	Node *cur = head;
	while (cur)
	{
		if (strcmp(cur->data.getUserName(),username) == 0)
		{
			return cur->data.getUserType();
		}
		cur = cur->next;
	}
	return 0;
}

int UserList::getStatusbyUsername(char* username)
{
	Node *cur = head;
	while (cur)
	{
		if (strcmp(cur->data.getUserName(),username) == 0)
		{
			return cur->data.getStatus();
		}
		cur = cur->next;
	}
	cout << "username " << username << " does not exist, some errors have occur\n";
	return 0;
}

//Filter by usertype admin
bool UserList::filterbyUserTypeAdmin()
{
	freeSubhead();
	int count=0;
	Node *cur = head;
	while(cur)
	{
		if(cur->data.getUserType() == 1 && cur->data.getStatus() != 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}

	if (count == 0)
	{
		cout << "No account with User Type Administrator\n";
		return false;
	}
	return true;
}

//Filter by usertype librarian
bool UserList::filterbyUserTypeLibrarian()
{
	freeSubhead();
	int count=0;
	Node *cur = head;
	while (cur)
	{
		if (cur->data.getUserType() == 2 && cur->data.getStatus() != 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}

	if (count == 0)
	{
		cout << "No account with User Type Librarian\n";
		return false;
	}
	return true;
}

//Filter by usertype Reader
bool UserList::filterbyUserTypeReader()
{
	freeSubhead();
	int count=0;
	Node*cur = head;
	while (cur)
	{
		if (cur->data.getUserType() == 3 && cur->data.getStatus() != 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}

	if (count == 0)
	{
		cout << "No account with User Type Reader\n";
		return false;
	}
	return true;
}

//Filter by user type -- Currently not use
bool UserList::filterbyUserType()
{
	int c;
	cout << "\t\t1. Filter by UserType Administrators\n"
		 << "\t\t2. Filter by UserType Librarian\n"
		 << "\t\t3. Filter by UserType Reader\n"
		 << "\t\t4. Show all\n";
	cout << "\t\tChoose: ";
	cin >> c;
	bool b;
	switch(c)
	{
		case 1:
			b = filterbyUserTypeAdmin();
			break;
		case 2:
			b = filterbyUserTypeLibrarian();
			break;
		case 3:
			b = filterbyUserTypeReader();
			break;
		default:
			showAllForAdmin();
			break;
	}
	if (b == false)
	{
		return false;
	}
	return true;
}

//Filter by account status
//num = 0:inactivated; 1:activated; 2:banned
bool UserList::filterbyAccStatus(int num)
{
	freeSubhead();
	int count=0;
	Node*cur = head;
	while (cur)
	{
		if (cur->data.getStatus() == num && cur->data.getStatus() != 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}
	
	if (count == 0)
	{
		cout << "No account found\n";
		return false;
	}
	return true;
}

//Filter by acc Status for librarian
bool UserList::filterbyAccStatusforLib(int num)
{
	freeSubhead();
	int count=0;
	Node*cur = head;
	while (cur)
	{
		if (cur->data.getStatus() == num && cur->data.getStatus() != 3 && cur->data.getUserType() == 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}

	if (count == 0)
	{
		cout << "No account found\n";
		return false;
	}
	return true;
}

//Filter by user name
bool UserList::filterbyUserName()
{
	freeSubhead();
	char username[100];
	cout << "Enter username: ";
	cin.getline(username,sizeof(username));
	//cin.get();

	int count=0;
	Node* cur = head;
	while (cur)
	{
		if (strstr(cur->data.getUserName(),username) != NULL && cur->data.getStatus() != 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}
	
	if (count == 0)
	{
		cout << "No account found\n";
		return false;
	}
	return true;
}

//Filter by username for librarian
bool UserList::filterbyUserNameforLib()
{
	freeSubhead();
	char username[100];
	cout << "Enter username: ";
	cin.getline(username,sizeof(username));
	//cin.get();

	int count=0;
	Node* cur = head;
	while (cur)
	{
		if (strstr(cur->data.getUserName(),username) != NULL && cur->data.getStatus() != 3 && cur->data.getUserType() == 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}

	if (count == 0)
	{
		cout << "No account found\n";
		return false;
	}
	return true;
}

//Filter By name
bool UserList::filterbyName()
{
	freeSubhead();
	char name[100];
	cout << "Enter name of user: ";
	cin.getline(name,sizeof(name));
	//cin.get();
	int count=0;
	Node*cur = head;
	while (cur)
	{
		if (strstr(cur->data.getName(),name) != NULL && cur->data.getStatus() != 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}
	if (count == 0)
	{
		cout << "No account found\n";
		return true;
	}
	return false;
}

//Filter by name for librarian
bool UserList::filterbyNameforLib()
{
	freeSubhead();
	char name[100];
	cout << "Enter name of user: ";
	cin.getline(name,sizeof(name));
	//cin.get();
	int count=0;
	Node*cur = head;
	while (cur)
	{
		if (strstr(cur->data.getName(),name) != NULL && cur->data.getStatus() != 3 && cur->data.getUserType() == 3)
		{
			++count;
			addNodetoSubList(cur);
		}
		cur = cur->next;
	}
	if (count == 0)
	{
		cout << "No account found\n";
		return true;
	}
	return false;
}

//Modify account -- Currently not use
void UserList::modifyAcc()
{
	if (subhead == NULL)
	{
		cout << "List has not loaded";
	}
	int c;
	Node *subcur;
	do 
	{
		cout << "Which account: ";
		cin >> c;
		subcur = subhead;
		if (c < 1)
		{
			cout << "Invalid option, you have to choose again\n";
			c = 0;
		}
		for (int j=1;j<c;++j)
		{
			if (subcur == NULL)
			{
				cout << "Invalid option, you have to choose again\n";
				j = c;
				c = 0;
				break;
			}
			subcur = subcur->next;
		}
	} while (c == 0);
	cout << endl;
	subcur->data.showInfo();
	cout << "\n1. Reset password\n"
		 << "2. Remove\n"
		 << "3. Ban account\n";
	cout << "Choose: ";
	cin >> c;
	
	switch(c)
	{
		case 1:
			subcur->data.changePassWord();
			break;
		case 2:
			{
				if (subcur == subhead)
				{
					Node* temp = subhead->next;
					delete head;
					subhead = temp;
				}
				else
				{
					Node *pre = subhead;
					while(pre->next != subcur)
					{
						pre = pre->next;
					}
					pre->next = subcur->next;
					delete subcur;
				}
				subcur = subhead;
				ofstream file;
				file.open("UserInfo.bin",ios::binary);
				while (subcur)
				{
					file.write((char*)&subcur->data,sizeof(subcur->data));
					subcur = subcur->next;
				}
				file.close();
				cout << "Successfully removed\n";
				loadUserList();
				break;
			}
		case 3:
			subcur->data.banAcc();
			break;
	}
}

//Ban account
void UserList::banAcc(int num)
{
	int c;
	char str[1000];
	//Ensure you want to ban this acc
	cout << "Are you sure you want to ban this account:\n"
		 << "1. Yes\n"
		 << "2. No\n";
	do 
	{
		cout << "Choose: ";
		cin.getline(str,sizeof(str));
		if (isNumber(str))
			c = convertStringtoNum(str);
		else
			c = 0;
		Node *subcur;
		Node *cur;
		switch(c)
		{
		case 1:
			//traverse to the selected node
			subcur = subhead;
			for (int i=1;i<num;++i)
			{
				subcur = subcur->next;
				//if the input number bigger than the number of node in sublist it will alert error
				if (subcur == NULL)
				{
					cout << "Invalid input, you have to choose again\n";
					cout << "Enter to continue...\n";
					cin.get();
					return;
				}
			}
			cur = head;
			while (cur)
			{
				if (strcmp(cur->data.getUserName(),subcur->data.getUserName()) == 0)
				{
					//Check if whether the selected acc has been banned or not
					if (cur->data.getStatus() == 2)
					{
						cout << "This account has already been banned\n";
						cout << "Enter to continue...\n";
						cin.get();
						return;
					}
					cur->data.setUserStatus(2);//set banned
					cout << "Account username " << cur->data.getUserName() << " has been banned\n";//announce success
					updateUserList();//write again the list to binary file
					freeHead();//free head
					freeSubhead();
					loadUserList();//load info back to list
					
					
					cout << "Enter to continue...\n";
					cin.get();
					return;
				}
				cur = cur->next;
			}
		case 2:
			return;
		default:
			c = 0;
			cout << "Invalid input, you have to choose again\n";
		}
	} while (c == 0);
	
}

//Unban account
void UserList::unbanAcc(int num)
{
	Node *subcur = subhead;
	for (int i=1;i<num;++i)
	{
		subcur = subcur->next;
		if (subcur == NULL)
		{
			cout << "Invalid input, you have to choose again\n";
			cout << "Enter to continue...\n";
			cin.get();
			return;
		}
	}
	Node *cur = head;
	while (cur)
	{
		if (strcmp(cur->data.getUserName(),subcur->data.getUserName()) == 0)
		{
			//Check whether the selected acc is unbanned or not
			if (cur->data.getStatus() != 2)
			{
				cout << "This account currently unban\n";
				cout << "Enter to continue...\n";
				cin.get();
				return;
			}
			//like ban account
			cur->data.setUserStatus(1);
			updateUserList();//Update new information to binary file
			cout << "Account username " << cur->data.getUserName() << " has been Unbanned\n";
			freeHead();// free head so that the list is ready to load new data
			freeSubhead();// head is free so subhead should be free
			loadUserList();// load new data to head list
			cout << "Enter to continue...\n";
			cin.get();
			return;
		}
		cur = cur->next;
	}
}

char *UserList::FindUsername(int num)
{
	Node *subcur = subhead;
	for (int i=1;i<num;++i)
	{
		subcur = subcur->next;
		if (subcur == NULL)
		{
			return NULL;
		}
	}
	return subcur->data.getUserName();
}
//delete account
void UserList::deleteAcc(char *username)
{
	int c;
	char str[1000];
	cout << "Are you sure you want to delete this account:\n"
		 << "1. Yes\n"
		 << "2. No\n";
	do 
	{
		cout << "Choose: ";
		cin.getline(str,sizeof(str));
		if (isNumber(str))
			c = convertStringtoNum(str);
		else
			c = 0;

		Node *cur;
		switch(c)
		{
		case 1:
			cur = head;
			while (cur)
			{
				if (strcmp(cur->data.getUserName(),username) == 0)
				{
					cur->data.setUserStatus(3);//Set status of the selected user to 3 (deleted)
					
					updateUserList();//update information and print announce
					cout << "Account username " << cur->data.getUserName() << " has been deleted\n";
					freeHead();// like unban
					freeSubhead();
					loadUserList();
					cout << "Enter to continue...\n";
					cin.get();
					return;
				}
				cur = cur->next;
			}
		case 2:
			return;
		default:
			c = 0;
			cout << "Invalid input, you have to choose again\n";
		}
	} while (c == 0);
}

//Reset password
void UserList::resetPassword(int num)
{
	Node *subcur = subhead;
	//traverse to the selected account
	for (int i=1;i<num;++i)
	{
		subcur = subcur->next;
		if (subcur == NULL)
		{
			cout << "Invalid input, you have to choose again\n";
			return;
		}
	}
	Node *cur = head;
	//reset pass in the head list not the sublist, but use the sublist to presentation and find the right user
	while (cur)
	{
		if (strcmp(cur->data.getUserName(),subcur->data.getUserName()) == 0)
		{
			//Set password to apcs11ctt
			cur->data.setPassword("apcs11ctt");
			cout << "This account's password has been reset\n";
			cout << "Enter to continue...\n";
			cin.get();
			return;
		}
	}
}

//add the node to sub list
void UserList::addNodetoSubList(Node *cur)
{
	Node *subcur;
	Node *newNode = new Node;
	newNode->data.copyInfo(cur->data);
	newNode->next = NULL;
	if (subhead == NULL)
	{
		subhead = newNode;
	}
	else
	{
		subcur = subhead;
		while (subcur->next)
		{
			subcur = subcur->next;
		}
		subcur->next = newNode;
	}
}

//Welcome User
void UserList::welcome( char *username )
{
	Node *cur = head;
	if (head == NULL)
	{
		cout << "@@ what's wrong";
	}
	while (cur)
	{
		if (strcmp(cur->data.getUserName(),username) == 0)
		{
			cout << "Hello " << cur->data.getName() << endl;
			return;
		}
		cur = cur->next;
	}
	cout << "You have login but can't find your real name\n"
		 << "What happened";
}

//Change the current login user
void UserList::changeYourPassword( char* username )
{
	//cin.get();
	Node *cur = head;
	while(cur)
	{
		if (strcmp(cur->data.getUserName(),username) == 0)
		{
			char password[100];
			cout << "Your old password: ";
			cin.getline(password,sizeof(password));
			if (cur->data.isRightPass(password))
			{
				cur->data.changePassWord();
				updateUserList();
				loadUserList();
				cout << "Your password has been updated\n";
				return;
			}
			else
			{
				cout << "Wrong password\n";
				return;
			}
		}
		cur = cur->next;
	}
}

//User only can input a choice in numbers
bool UserList::isNumber(char *cChoice)
{
	for (int i = 0 ;i<strlen(cChoice);++i)
	{
		if (cChoice[i] < 48 || cChoice[i] > 57)
		{
			return false;
		}
	}
	return true;
}

//Convert a string to number if string content only digit character
int UserList::convertStringtoNum( char *str )
{
	int num = 0;
	for (int i=0;i<strlen(str);++i)
	{
		num *= 10;
		num += (str[i]-48);
	}
	return num;
}

//Activate an user
void UserList::activateAnUser( int num )
{
	Node *subcur = subhead;
	for (int i = 1;i < num;++i)
	{
		if (subcur->next)
		{
			subcur = subcur->next;
		}
		else
		{
			cout << "Invalid number, you have to do it again\n";
			return;
		}
	}
	Node *cur = head;
	while (cur)
	{
		if (strcmp(cur->data.getUserName(),subcur->data.getUserName()) == 0)
		{
			//set the account status from 0(inactivate) to 1(activate)
			cur->data.setUserStatus(1);
			cout << "User has been activated successfully\n";
			updateUserList();
			freeHead();
			loadUserList();
			return;
		}
		cur = cur->next;
	}
	
}

//Activate some users
void UserList::activateSomeUsers( int *ul )
{
	Node *subcur;
	int j = 0;
	while (ul[j] != 0)
	{
		subcur = subhead;
		for (int i=1;i<ul[j];++i)
		{
			if (subcur->next)
			{
				subcur = subcur->next;
			}
			else
			{
				cout << "User " << ul[j] <<"th activate fail\n";
				subcur = subcur->next; // traverse subcur so that the subcur is NULL and it can not set User Status
			}
		}
		if (subcur != NULL)
		{
			Node *cur = head;
			while (cur)
			{
				if (strcmp(cur->data.getUserName(),subcur->data.getUserName()) == 0)
				{
					cur->data.setUserStatus(1);
					cout << "User " << ul[j] << "th has been activated successfully\n";	
				}
				cur = cur->next;
			}
			
		}
		++j;
	}
	updateUserList();
	freeHead();
	loadUserList();
}

//Activate all users
void UserList::activateAllUser()
{
	Node* cur = head;
	while (cur)
	{
		if (cur->data.getStatus() == 0)
		{
			cur->data.setUserStatus(1);
		}
		cur = cur->next;
	}
	cout << "All users have been activated successfully\n";
	updateUserList();
	freeHead();
	loadUserList();
}

//Delete linked list with Subhead node is the first node
void UserList::freeSubhead()
{
	Node* cur = subhead;
	while (subhead)
	{
		subhead = subhead->next;
		delete cur;
		cur = subhead;
	}
}

//Delete linked list with Head node is the first node
void UserList::freeHead()
{
	Node* cur = head;
	while (head)
	{
		head = head->next;
		delete cur;
		cur = head;
	}
}

// 16/5
//Show User Info
void UserList::showUserInfo(char *username)
{
	Node *cur = head;
	while (cur)
	{
		if (strcmp(cur->data.getUserName(),username) == 0)
		{
			cout << "--------------------\n";
			cout << "Your infomation:\n";
			cur->data.showInfo();
			cout << "--------------------\n";
			return ;
		}
		cur = cur->next;
	}
	cout <<"Can't find your information!\n";
	return ;
}

//sort by name (ascending)
void UserList::sortbyNameAscending()
{
	Node* cur = subhead;
	char smallest[100];
	strcpy(smallest,subhead->data.getName());
	Node* temp;
	while(cur->next)
	{
		if(strcmp(smallest,cur->next->data.getName())>0)
		{
			temp = cur->next;
			cur->next = temp->next;
			temp->next = subhead;
			subhead = temp;
			strcpy(smallest,subhead->data.getName());
		}
		else
			cur = cur->next;
	}

	cur = subhead;
	while(cur->next)
	{
		strcpy(smallest,cur->next->data.getName());
		temp= cur->next;
		while(temp->next)
		{
			if(strcmp(smallest,temp->next->data.getName())>0)
			{
				strcpy(smallest,temp->next->data.getName());
				Node* TEMP;
				TEMP = temp->next;
				temp->next = TEMP->next;
				TEMP->next = cur->next;
				cur->next = TEMP;
			}
			else
				temp = temp->next;
		}
		cur = cur->next;
	}
}

//sort by name (descending)
void UserList::sortbyNameDescending()
{
	Node* cur = subhead;
	char biggest[100];
	strcpy(biggest,subhead->data.getName());
	Node* temp;
	while(cur->next)
	{
		if(strcmp(biggest,cur->next->data.getName())<0)
		{
			temp = cur->next;
			cur->next = temp->next;
			temp->next = subhead;
			subhead = temp;
			strcpy(biggest,subhead->data.getName());
		}
		else
			cur = cur->next;
	}

	cur = subhead;
	while(cur->next)
	{
		strcpy(biggest,cur->next->data.getName());
		temp= cur->next;
		while(temp->next)
		{
			if(strcmp(biggest,temp->next->data.getName())<0)
			{
				strcpy(biggest,temp->next->data.getName());
				Node* TEMP;
				TEMP = temp->next;
				temp->next = TEMP->next;
				TEMP->next = cur->next;
				cur->next = TEMP;
			}
			else
				temp = temp->next;
		}
		cur = cur->next;
	}
}

//sort by user name (ascending)
void UserList::sortbyUserNameAscending()
{
	Node* cur = subhead;
	char smallest[100];
	strcpy(smallest,subhead->data.getUserName());
	Node* temp;
	while(cur->next)
	{
		if(strcmp(smallest,cur->next->data.getUserName())>0)
		{
			temp = cur->next;
			cur->next = temp->next;
			temp->next = subhead;
			subhead = temp;
			strcpy(smallest,subhead->data.getUserName());
		}
		else
			cur = cur->next;
	}

	cur = subhead;
	while(cur->next)
	{
		strcpy(smallest,cur->next->data.getUserName());
		temp= cur->next;
		while(temp->next)
		{
			if(strcmp(smallest,temp->next->data.getUserName())>0)
			{
				strcpy(smallest,temp->next->data.getUserName());
				Node* TEMP;
				TEMP = temp->next;
				temp->next = TEMP->next;
				TEMP->next = cur->next;
				cur->next = TEMP;
			}
			else
				temp = temp->next;
		}
		cur = cur->next;
	}
}

//sort by user name (descending)
void UserList::sortbyUserNameDescending()
{
	Node* cur = subhead;
	char biggest[100];
	strcpy(biggest,subhead->data.getUserName());
	Node* temp;
	while(cur->next)
	{
		if(strcmp(biggest,cur->next->data.getUserName())<0)
		{
			temp = cur->next;
			cur->next = temp->next;
			temp->next = subhead;
			subhead = temp;
			strcpy(biggest,subhead->data.getUserName());
		}
		else
			cur = cur->next;
	}

	cur = subhead;
	while(cur->next)
	{
		strcpy(biggest,cur->next->data.getUserName());
		temp= cur->next;
		while(temp->next)
		{
			if(strcmp(biggest,temp->next->data.getUserName())<0)
			{
				strcpy(biggest,temp->next->data.getUserName());
				Node* TEMP;
				TEMP = temp->next;
				temp->next = TEMP->next;
				TEMP->next = cur->next;
				cur->next = TEMP;
			}
			else
				temp = temp->next;
		}
		cur = cur->next;
	}
}

//sort by account status (ascending)
void UserList::sortbyAccountStatusAscending()
{
	Node* cur = subhead;
	int smallest = subhead->data.getStatus();
	Node* temp;
	while(cur->next)
	{
		if(cur->next->data.getStatus()<smallest)
		{
			temp = cur->next;
			cur->next = temp->next;
			temp->next = subhead;
			subhead = temp;
			smallest = subhead->data.getStatus();
		}
		else
			cur = cur->next;
	}

	cur = subhead;
	while(cur->next)
	{
		smallest = cur->next->data.getStatus();
		temp= cur->next;
		while(temp->next)
		{
			if(temp->next->data.getStatus()<smallest)
			{
				smallest = temp->next->data.getStatus();
				Node* TEMP;
				TEMP = temp->next;
				temp->next = TEMP->next;
				TEMP->next = cur->next;
				cur->next = TEMP;
			}
			else
				temp = temp->next;
		}
		cur = cur->next;
	}
}

//sort by account status (descending)
void UserList::sortbyAccountStatusDescending()
{
	Node* cur = subhead;
	int biggest = subhead->data.getStatus();
	Node* temp;
	while(cur->next)
	{
		if(cur->next->data.getStatus()>biggest)
		{
			temp = cur->next;
			cur->next = temp->next;
			temp->next = subhead;
			subhead = temp;
			biggest = subhead->data.getStatus();
		}
		else
			cur = cur->next;
	}

	cur = subhead;
	while(cur->next)
	{
		biggest = cur->next->data.getStatus();
		temp= cur->next;
		while(temp->next)
		{
			if(temp->next->data.getStatus()>biggest)
			{
				biggest = temp->next->data.getStatus();
				Node* TEMP;
				TEMP = temp->next;
				temp->next = TEMP->next;
				TEMP->next = cur->next;
				cur->next = TEMP;
			}
			else
				temp = temp->next;
		}
		cur = cur->next;
	}
}

//Write list of user info to XML file
void UserList::WriteUserInfoXMLfile()
{
	Node *cur = subhead;
	char name[100];
	cout << "File name(Ex: save):";
	cin.getline(name,100);
	strcat(name,".xml");
	ofstream file;
	file.open(name,ios::out);
	if (file.good()==false)
		return ;
	file <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
	file << "<User>" << endl;
	while(cur)
	{
		file << "\t<UserInfo>"<<endl;
		file << "\t\t<Username>"<<cur->data.getUserName()<<"</Username>"<<endl;
		file << "\t\t<Name>"<<cur->data.getName()<<"</Name>"<<endl;
		file << "\t\t<DayofBirth>"<<cur->data.getDay()<<"/"<<cur->data.getmonth()<<"/"<<cur->data.getyear()<<"</DayofBirth>"<<endl;
		file << "\t\t<IdentityNumber>"<<cur->data.getID()<<"</IdentityNumber>"<<endl;
		file << "\t\t<Address>"<<cur->data.getAddress()<<"</Address>"<<endl;
		if(cur->data.getSex()==true)
			file << "\t\t<Sex>male</Sex>"<<endl;
		else
			file << "\t\t<Sex>female</Sex>"<<endl;
		if(cur->data.getStatus()==0)
			file << "\t\t<Status>inactivated</Status>"<<endl;
		else
			if(cur->data.getStatus()==1)
				file << "\t\t<Status>activated</Status>"<<endl;
			else
				file << "\t\t<Status>baned</Status>"<<endl;
		file <<"\t</UserInfo>"<<endl;
		cur = cur->next;
	}
	file << "</User>" << endl;
	file.close();

}

//Write list of user info to CSV file
void UserList::WriteUserInfoCSVfile()
{
	Node *cur = subhead;
	char name[100];
	cout << "File name(Ex: save):";
	cin.getline(name,100);
	strcat(name,".csv");
	ofstream file;
	file.open(name,ios::out);
	if (file.good()==false)
		return ;

	file << "Username,"
		 << "Name,"
		 << "Day of Birth,"
		 << "ID,"
		 << "Address,"
		 << "Sex,"
		 << "Status"<<endl;

	while(cur)
	{
		file <<cur->data.getUserName()<<","
			<<cur->data.getName()<<","
			<<cur->data.getDay()<<"/"<<cur->data.getmonth()<<"/"<<cur->data.getyear()<<","
			<<cur->data.getID()<<","
			<<cur->data.getAddress()<<",";
		if(cur->data.getSex()==true)
			file << "male,";
		else
			file << "female,";
		if(cur->data.getStatus()==0)
			file << "inactivated"<<endl;
		else
			if(cur->data.getStatus()==1)
				file << "activated"<<endl;
			else
				file << "baned"<<endl;

		cur = cur->next;
	}
	file.close();
}

void UserList::sortbyUserTypeAscending()
{
	Node* cur = subhead;
	int smallest = subhead->data.getUserType();
	Node* temp;
	while(cur->next)
	{
		if(cur->next->data.getUserType()<smallest)
		{
			temp = cur->next;
			cur->next = temp->next;
			temp->next = subhead;
			subhead = temp;
			smallest = subhead->data.getUserType();
		}
		else
			cur = cur->next;
	}

	cur = subhead;
	while(cur->next)
	{
		smallest = cur->next->data.getUserType();
		temp= cur->next;
		while(temp->next)
		{
			if(temp->next->data.getUserType()<smallest)
			{
				smallest = temp->next->data.getUserType();
				Node* TEMP;
				TEMP = temp->next;
				temp->next = TEMP->next;
				TEMP->next = cur->next;
				cur->next = TEMP;
			}
			else
				temp = temp->next;
		}
		cur = cur->next;
	}
}

void UserList::sortbyUserTypeDescending()
{
	Node* cur = subhead;
	int biggest = subhead->data.getUserType();
	Node* temp;
	while(cur->next)
	{
		if(cur->next->data.getUserType()>biggest)
		{
			temp = cur->next;
			cur->next = temp->next;
			temp->next = subhead;
			subhead = temp;
			biggest = subhead->data.getUserType();
		}
		else
			cur = cur->next;
	}

	cur = subhead;
	while(cur->next)
	{
		biggest = cur->next->data.getUserType();
		temp= cur->next;
		while(temp->next)
		{
			if(temp->next->data.getUserType()>biggest)
			{
				biggest = temp->next->data.getUserType();
				Node* TEMP;
				TEMP = temp->next;
				temp->next = TEMP->next;
				TEMP->next = cur->next;
				cur->next = TEMP;
			}
			else
				temp = temp->next;
		}
		cur = cur->next;
	}
}